﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;

namespace Ymatou.UserAuth.Utility
{
    public static class ClientIpInfo
    {
        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <returns>客户端IP</returns>
        /// <remarks>
        /// 一、没有使用代理服务器的情况：
        /// REMOTE_ADDR = 您的 IP
        /// HTTP_VIA = 没数值或不显示
        /// HTTP_X_FORWARDED_FOR = 没数值或不显示
        /// 二、使用透明代理服务器的情况：Transparent Proxies
        /// REMOTE_ADDR = 最后一个代理服务器 IP 
        /// HTTP_VIA = 代理服务器 IP
        /// HTTP_X_FORWARDED_FOR = 您的真实 IP ，经过多个代理服务器时，这个值类似如下：203.98.182.163, 203.98.182.163, 203.129.72.215。
        /// 这类代理服务器还是将您的信息转发给您的访问对象，无法达到隐藏真实身份的目的。
        /// 三、使用普通匿名代理服务器的情况：Anonymous Proxies
        /// REMOTE_ADDR = 最后一个代理服务器 IP 
        /// HTTP_VIA = 代理服务器 IP
        /// HTTP_X_FORWARDED_FOR = 代理服务器 IP ，经过多个代理服务器时，这个值类似如下：203.98.182.163, 203.98.182.163, 203.129.72.215。
        /// 隐藏了您的真实IP，但是向访问对象透露了您是使用代理服务器访问他们的。
        /// 四、使用欺骗性代理服务器的情况：Distorting Proxies
        /// REMOTE_ADDR = 代理服务器 IP 
        /// HTTP_VIA = 代理服务器 IP 
        /// HTTP_X_FORWARDED_FOR = 随机的 IP ，经过多个代理服务器时，这个值类似如下：203.98.182.163, 203.98.182.163, 203.129.72.215。
        /// 告诉了访问对象您使用了代理服务器，但编造了一个虚假的随机IP代替您的真实IP欺骗它。
        /// 五、使用高匿名代理服务器的情况：High Anonymity Proxies (Elite proxies)
        /// REMOTE_ADDR = 代理服务器 IP
        /// HTTP_VIA = 没数值或不显示
        /// HTTP_X_FORWARDED_FOR = 没数值或不显示 ，经过多个代理服务器时，这个值类似如下：203.98.182.163, 203.98.182.163, 203.129.72.215。
        /// </remarks>
        /// ------------------------------------------------
        /// Change History:
        /// Date			Who		            Changes Made
        /// 2010-5-11		Lasko		       Mark method
        /// -------------------------------------------------
        public static string GetClientIp()
        {
            try
            {
                if (HttpContext.Current == null) return string.Empty;
                // get cdn ip if exists
                string clientIp = HttpContext.Current.Request.ServerVariables["HTTP_Cdn_Src_Ip"];
                if (!string.IsNullOrEmpty(clientIp))
                {
                    return clientIp;
                }

                // get default ip
                clientIp = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

                // get forward list (from proxy)
                string forwardStr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

                if (!string.IsNullOrEmpty(forwardStr))
                {
                    // from proxy
                    string[] forwardList = forwardStr.Split(',');
                    if (forwardList.Length >= 2 || forwardList.Length == 1)
                    {
                        return forwardList[0].Trim();
                    }

                    if (!forwardStr.StartsWith("10."))
                    {
                        return forwardStr;
                    }
                }

                // return default ip
                return clientIp;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }
    }
}
